package controller

import (
	"encoding/json"
	"fmt"
	"gin-demo/model"
	"gin-demo/param"
	"gin-demo/service"
	"gin-demo/tool"
	"os"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/go-basic/uuid"
)

type MemberController struct {
}

// api
func (mc *MemberController) Router(e *gin.Engine) {
	e.GET("/api/sendcode", mc.sendSmsCode)
	e.POST("/api/login_sms", mc.smsLogin)
	e.GET("/api/captcha", mc.captcha)
	e.GET("/api/vertifycha", mc.vertifycha)
	e.POST("/api/login_pwd", mc.nameLogin)
	e.POST("/api/upload/avator", mc.uploadAvator)
	e.POST("/api/userinfo", mc.getUserInfo)
}

// cookie保存在客户端（浏览器），session存在服务端，两者选择一种方式即可
// 根据用户的请求是否携带 cookie 判断是否需要登录才能展示信息
func (mc *MemberController) getUserInfo(c *gin.Context) {
	cookie, err := tool.CookieAuth(c)
	if err != nil {
		c.Abort()
		tool.Failed(c, "您还未登录，请先登录")
		return
	}

	ms := service.MemberService{}
	member := ms.GetUserInfo(cookie.Value)
	if member != nil {
		tool.Success(c, map[string]interface{}{
			"id":            member.Id,
			"user_name":     member.UserName,
			"mobile":        member.Mobile,
			"register_time": member.RegisterTime,
			"avatar":        member.Avatar,
			"balance":       member.Balance,
			"city":          member.City,
		})
		return
	}
	tool.Failed(c, "获取信息失败")
}

// 头像上传
func (mc *MemberController) uploadAvator(c *gin.Context) {
	// 1, 解析上传参数
	userId := c.PostForm("user_id")
	fmt.Println("user_id", userId)
	file, err := c.FormFile("avatar")
	if err != nil || userId == "" {
		fmt.Println("file", file)
		tool.Failed(c, "参数解析失败")
		return
	}

	// 2, 判断是否用户是否已经登录
	sess := tool.GetSession(c, "user_"+userId)
	if sess == nil {
		tool.Failed(c, "参数不合法")
		return
	}
	var member model.Member
	json.Unmarshal(sess.([]byte), &member)

	// 3, 文件保存到本地
	uuid := uuid.New()
	now := strconv.FormatInt(time.Now().Unix(), 10)

	fileName := "./uploadfile" + now + "." + uuid
	err = c.SaveUploadedFile(file, fileName)
	if err != nil {
		tool.Failed(c, "头像更新失败")
		return
	}
	// 将文件上传到 fastDFS 系统
	fileID := tool.UploadFile(fileName)
	if fileID != "" {
		// 删除本地的 uploadfile 下的文件
		os.Remove(fileName)

		/*
			// 这里是保存到本地 uploadfile 中
			// 4,将保存后的文件路径,保存到用户表中
			ms := service.MemberService{}
			fileName = fileName[1:] // 截取 . 符号后面的字符串
			path := ms.UploadAvatar(member.Id, fileName)
			if path != "" {
				tool.Success(c, "http://localhost:8099"+path)
				return
			}
		*/
		// 这里保存到 fastDFS 系统中
		ms := service.MemberService{}
		path := ms.UploadAvatar(member.Id, fileID)
		if path != "" {
			tool.Success(c, tool.FileServerAddr()+"/"+path)
			return
		}
	}
	tool.Failed(c, "上传失败")
}

// 用户名 + 密码 + 验证码登录
func (mc *MemberController) nameLogin(c *gin.Context) {
	// 1, 解析登录参数
	var loginParam param.LoginParam

	err := tool.Decode(c.Request.Body, &loginParam)
	if err != nil {
		tool.Failed(c, "请求参数解析是失败")
		return
	}
	// 2, 验证验证码
	validate := tool.CaptVerify(loginParam.Id, loginParam.Value)
	if !validate {
		tool.Failed(c, "验证码不正确,请重新验证")
		return
	}

	// 3, 登录
	ms := service.MemberService{}
	member := ms.Login(loginParam.Name, loginParam.Password)
	if member.Id != 0 {

		// 这为了测试，使用了cookie和session的方式
		c.SetCookie("user_cookie", strconv.Itoa(int(member.Id)), 10*60, "/", "localhost", true, true)

		// 信息保存到 session
		sess, err := json.Marshal(member)
		if err != nil {
			tool.Failed(c, "解析参数失败")
			return
		}
		err = tool.SetSession(c, "user_"+fmt.Sprint(member.Id), sess)
		if err != nil {
			tool.Failed(c, "登录失败")
			return
		}
		tool.Success(c, &member)
		return
	}

	tool.Failed(c, "登录失败")
}

// 发送短信
// http://localhost:8099/api/sendcode?phone=15436244961
func (mc *MemberController) sendSmsCode(c *gin.Context) {
	// 发送验证码
	phone, exit := c.GetQuery("phone")

	if !exit {
		tool.Failed(c, "短信服务参数解析失败")
		return
	}

	ms := service.MemberService{}
	isSend := ms.Sendcode(phone)
	if isSend {
		tool.Success(c, "短信发送成功")
		return
	}

	tool.Failed(c, "短信发送失败")
}

// 登录验证
// http://localhost:8099/api/login_sms
func (m *MemberController) smsLogin(c *gin.Context) {
	var smsLoginParam param.SmsLoginParam

	err := tool.Decode(c.Request.Body, &smsLoginParam)

	if err != nil {
		tool.Failed(c, "请求参数解析失败")
		return
	}

	// 完成手机+验证码登录
	us := service.MemberService{}
	member := us.SmsLogin(smsLoginParam)

	if member != nil {

		// 这为了测试，使用了cookie和session的方式
		c.SetCookie("user_cookie", strconv.Itoa(int(member.Id)), 10*60, "/", "localhost", true, true)

		// 信息保存到 session
		sess, err := json.Marshal(member)
		if err != nil {
			tool.Failed(c, "解析参数失败")
			return
		}
		err = tool.SetSession(c, "user_"+fmt.Sprint(member.Id), sess)
		if err != nil {
			tool.Failed(c, "登录失败")
			return
		}
		tool.Success(c, member)
		return
	}

	tool.Failed(c, "登录失败")
}

// 生成图形化验证码
// http://localhost:8099/api/captcha
func (mc *MemberController) captcha(c *gin.Context) {

	id, base64Blog, err := tool.GenerateCaptcha(c)
	fmt.Println(id)
	fmt.Println(base64Blog)
	fmt.Println(err)

	captchaResult := tool.GetCaptchaReault(id, base64Blog, "1111")

	tool.Success(c, captchaResult)
}

// 判断验证码的是否正确
func (mc *MemberController) vertifycha(c *gin.Context) {

	var captcha tool.CaptchaReault
	err := tool.Decode(c.Request.Body, &captcha)
	if err != nil {
		tool.Failed(c, "参数解析失败")
		return
	}
	fmt.Print("<>>>>>>id", captcha.Id, "VertifyValue:", captcha.VertifyValue)
	result := tool.CaptVerify(captcha.Id, captcha.VertifyValue)
	if result {
		fmt.Println("验证通过")
	} else {
		fmt.Println("验证失败")
	}
}
